package com.cheng.example.geektime.designpatterns.j57.writeventbusauthor;

import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * CopyOnWriteArraySet是“线程安全”的集合，而HashSet是非线程安全的。
 *
 *   下面是“多个线程同时操作并且遍历集合set”的示例
 *   (01) 当set是CopyOnWriteArraySet对象时，程序能正常运行。
 *   (02) 当set是HashSet对象时，程序会产生ConcurrentModificationException异常。
 *
 * @author jpgong
 *
 */
public class CopyOnWriteArraySetTest {

    //定义一个CopyOnWriteArraySet对象，用来存放线程内容。
    private static CopyOnWriteArraySet<String> set = new CopyOnWriteArraySet<String>();

    public static void main(String[] args) throws InterruptedException {
        // 同时启动两个线程对set进行操作！
        CopyOnWriteArraySetTest test = new CopyOnWriteArraySetTest();
        test.new WriteThread("ta").start();
        //让一个进程先进入睡眠模式,等一个进程结束后再执行下一个进程
//        Thread.sleep(600);
        test.new WriteThread("tb").start();
    }

    private static void printAll() {
        String value = null;
        //返回按照元素添加顺序在此 set中包含的元素迭代器。
        Iterator<String> iter = set.iterator();
        //将当前集合中存在的元素通过迭代器输出
        while(iter.hasNext()) {
            value = (String)iter.next();
            System.out.print(value + ", ");
        }
        System.out.println();
    }

    /**
     * 定义一个写进程，用于往CopyOnWriteArraySet对象中写内容
     * @author jpgong
     *
     */
    class WriteThread extends Thread {
        WriteThread(String name) {
            super(name);
        }
        @Override
        public void run() {
            int i = 0;
            while (i++ < 5) {
                // “线程名” + "-" + "序号",将写好的元素添加到Set对象上去
                String val = Thread.currentThread().getName() + "-" + i;
                set.add(val);
                // 通过“Iterator”遍历set。
                printAll();
            }
        }
    }
}
